<?php
/*
 * File: PaymentRechargeController.php
 * Project: NewDemo
 * Created Time: 2024-07-08 05:18:42 pm
 * Author: WangYuQiang && WangpeiGang (719404171@qq.com)
 * -----
 * Last Modified: 2025-04-02 10:52:41 am
 * Modified By: WangYuQiang (719404171@qq.com>)
 * -----
 * Copyright (c) 2023 - 2024 成都睿創科技有限公司
 */

namespace App\Http\Controllers\Api;

use App\Models\User;
use App\Models\SystemInfo;
use App\Models\UserWalletRecord;
use App\Http\Controllers\Controller;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Refund;
use PayPal\Api\Transaction;
use PayPal\Api\ExecutePayment;
use PayPal\Api\PaymentExecution;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Api\Sale;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Notifications\Notifiable;
//Stripe
use Stripe\Customer;
use Stripe\Checkout\Session;
use Laravel\Cashier\Cashier;
use Laravel\Cashier\Checkout;
use App\Http\Controllers\Api\MailController;
use App\Http\Controllers\Common\GeTuiController;

class PaymentRechargeController extends Controller{

    private $clientId;
    private $clientSecret;
    private $apiContext;
    private $Order;
    private $User;
    
    
    public function __construct(){
        $this->User = new User();
        // paypal充值回調-成功鏈接
        $this->paypal_recharge_success = config('services.basics.base_uri').'/api/PaypalRechargeSuccess';
        // paypal充值回調-失敗鏈接
        $this->paypal_recharge_error = config('services.basics.base_uri').'/api/PaypalRechargeError';
        // Stripe充值
        $this->stripe_recharge= config('services.basics.base_uri').'/api/StripeRecharge';
        // Stripe充值回調-成功鏈接
        $this->stripe_recharge_success = config('services.basics.base_uri').'/api/StripeRechargeSuccess';
        // Stripe充值回調-失敗鏈接
        $this->stripe_recharge_error = config('services.basics.base_uri').'/api/StripeRechargeError';
        // 支付成功鏈接
        $this->success_uri = config('services.basics.base_uri').'/api/success';
        // 支付失敗鏈接
        $this->error_uri = config('services.basics.base_uri').'/api/error';
        //設置支付成功返回語言
        $this->language = app('global_language')  == "en" ? "en" : "zh";

        // paypal支付設置
        if (app('global_paypal_env') == 1) {
            $this->mode = 'live';
        }else{
            $this->mode = 'sandbox';
        }
        $this->clientId = app('global_client_id');
        $this->clientSecret = app('global_paypal_secret');
        $this->apiContext = new ApiContext(
            new OAuthTokenCredential(
                $this->clientId,
                $this->clientSecret
            )
        );

        $this->apiContext->setConfig(array(
                'mode' => $this->mode,//支付環境
                'log.LogEnabled' => true,
                'log.FileName' => '../storage/logs/PayPal.log',
                'log.LogLevel' => 'FINE',
                'cache.enabled' => false
            ));
    }


    
/**************************************************產品支付*************************************************************************/

    /**
     * @param Request $request
     * @return array
     * 充值
     */
    public function PaymentRecharge(Request $request){
        //接收参数
        $info=$request->post();
        //用户id
        $info['user_id']=auth('api')->user()->user_id;
        if($info['payment_mode']==1){
            // 支付方式: 1：paypal  
            return $this->PaypalRecharge($info);
        }elseif ($info['payment_mode']==2) {
            // 支付方式:   2：Stripe
            // Stripe支付最小金額為4元
            if($info['recharge_money'] < 4){
                return $this->error(__('api.stripe_lowest'));
            }
            $result['url']=$this->stripe_recharge."?recharge_money=".$info['recharge_money']."&user_id=".$info['user_id'];
            return $result;
        }
   

    }



/**************************************************支付方式-Paypal支付*************************************************************************/
    /**
     * 調起充值支付
     * @param $money
     * @param $userId
     * @return null|string
     * data['recharge_money']
     * data['user_id']
     */
    public function PaypalRecharge($data){
        // 创建支付对象
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');
        // 创建项目列表
        $item = new Item();
        $item->setName('賬戶充值')->setCurrency('HKD') ->setQuantity(1)->setPrice($data['recharge_money']);
        $itemList = new ItemList();
        $itemList->setItems([$item]);
        
        //設置運費  支付金額
        $details = new Details();
        $details->setShipping(0)->setTax(0)->setSubtotal($data['recharge_money']);
        //設置總金額  運費+產品支付
        $amount = new Amount();
        $amount->setCurrency("HKD")->setTotal($data['recharge_money'])->setDetails($details);
        // 设置重定向的URL
        $transaction = new Transaction();
        $transaction->setAmount($amount)->setItemList($itemList) ->setDescription("Payment description")->setInvoiceNumber(uniqid());
        $redirectUrls = new RedirectUrls();
        $redirectUrls->setReturnUrl($this->paypal_recharge_success."?success=true&user_id=".$data['user_id']."&recharge_money=".$data['recharge_money'])
                     ->setCancelUrl($this->paypal_recharge_error."?success=false&user_id=".$data['user_id']."&recharge_money=".$data['recharge_money']);
        // 创建支付
        $payment = new Payment();
        $payment->setIntent("sale")->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions(array(array('amount' => $amount, 'item_list' => $itemList)));
        $payment->create($this->apiContext);
        //生成地址
        $approvalUrl = $payment->getApprovalLink();
        $result['url']=$approvalUrl;
        return $result;
    }

    /**
     * 充值回調
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function PaypalRechargeSuccess(Request $request){
        $user_id = $request->get('user_id');//用戶ID
        $recharge_money = $request->get('recharge_money');//充值金額
        $success = $request->get('success');
		$paymentId = $request->get('paymentId');//支付ID
        $PayerID=$request->get('PayerID');//支付人ID
        $orderinfo = User::where('user_id',$user_id)->select('*')->first()->toArray();
        if (!empty($success)) {     
			$payment = Payment::get($paymentId, $this->apiContext);
			$execution = new PaymentExecution();
			$execution->setPayerId($PayerID);
            try {
                DB::beginTransaction();
                $result = $payment->execute($execution, $this->apiContext)->toArray();
                $refund_id = $result['transactions'][0]['related_resources'][0]['sale']['id'];
                // $this->LogInfo('paypal退款ID:' , $orderRefundId , 'PaypalCallback' , true);//开启日志记录
                //支付完成更改用戶信息(推送 郵箱 系統消息  )
                $effects=$this->RechargeComplete($user_id, $recharge_money ,1);// 支付完成更改用戶信息
                if(!empty($effects)){
                    DB::commit();
                    //支付完成
                    if($this->language == "en" ){
                        return view('Payment/en_Success');
                    }else{
                        return view('Payment/Success');
                    }
                }else{
                    DB::rollBack();
                    // 支付不成功，退款
                    $Refund['refund_id']=$refund_id;//退款id
                    $Refund['recharge_money']=$recharge_money;//退款金額
                    $returnInfo = $this->PayPalReturnMoney($Refund);
                    //支付失敗
                    if($this->language == "en" ){
                        return view('Payment/en_Error');
                    }else{
                        return view('Payment/Error');
                    }
                }
            } catch (Exception $e) {
                //支付失敗
                if($this->language == "en" ){
                    return view('Payment/en_Error');
                }else{
                    return view('Payment/Error');
                }
            }
        } else {
            //支付失敗
            if($this->language == "en" ){
                return view('Payment/en_Error');
            }else{
                return view('Payment/Error');
            }
        }
    }
    /**
     * @param $data
     * @return array
     * PayPal退款
     */
    public function PayPalReturnMoney($data){
        try {
            $refund_id = $data['refund_id'];  //异步加调中拿到的id
            $amt = new Amount();
            $amt->setCurrency('HKD')->setTotal($data['recharge_money']);  // 退款的费用
            $refund = new Refund();
            $refund->setAmount($amt);
            $sale = new Sale();
            $sale->setId($refund_id);
            $refundedSale = $sale->refund($refund, $this->apiContext);
        } catch (\Exception $e) {
            // PayPal无效退款
            return false;

        }
        // 退款完成
        return true;
    }


/**************************************************支付方式-Stripe支付*************************************************************************/
    /**
     * @param Request $request
     * @return array
     * 支付方式--Stripe充值
     * data['recharge_money']
     * 卡号  Visa:4242424242424242  4000000320000021 4000000760000002
     * 测试卡号位置：https://docs.stripe.com/testing#international-cards
     */
    public function StripeRecharge(Request $request){
        $user_id = $request->get('user_id');//用户id
        $recharge_money = $request->get('recharge_money');//充值金額
        //查看有沒有該客戶，沒有就創建
        $UserInfo = $this->User->where('user_id',$user_id)->first();
        //修復stripe_id是空的時候報錯，只能是NULL
        if (empty($UserInfo['stripe_id'])) {
            $this->User->where('user_id',$UserInfo['user_id'])->update(['stripe_id'=>NULL]);
        }
        // 如果你想为给定的计费模型检索 Stripe 客户对象，但不确定该计费模型是否已经是 Stripe 中的客户，
        // 则可以使用 createOrGetStripeCustomer 方法。 如果尚不存在，此方法将在 Stripe 中创建一个新客户：
        $info['name']=$UserInfo['user_name'];
        $info['phone']=$UserInfo['user_phone'];
        // $info['email']=$UserInfo['user_email'];
        $stripeCustomer = $this->User->where('user_id',$user_id)->first()->createOrGetStripeCustomer($info);
        //創建完成-end
        // Stripe支付
        //产品金额(單位：分)
        $amount = $recharge_money * 100;//充值金額
        //Stripe支付最小金額為4元
        if($amount < 400 ){
            return $this->error(__('api.stripe_lowest'));
        }
        $name='賬戶充值';//产品名称
        $quantity = 1;//产品数量 
        $sessionOptions=[
            'mode'        => 'payment',
            'locale'      => 'zh-HK', //设置为繁体中文
            'success_url' => $this->stripe_recharge_success."?success=true&user_id=".$user_id ."&recharge_money=".$recharge_money.'&session_id={CHECKOUT_SESSION_ID}',// 同步回调
            'cancel_url'  => $this->stripe_recharge_error."?success=false&user_id=".$user_id."&recharge_money=".$recharge_money,// 异步回调
            'metadata'    => [
                'user_id' => $user_id,
                'recharge_money' => $recharge_money,
            ]
        ];
        $UserCheckout=$this->User->where('user_id',$user_id)->first();
        $checkout =$UserCheckout->checkoutCharge($amount, $name, $quantity, $sessionOptions );
        return  $checkout;   
    }

    /**
     * @param Request $request
     * @return array
     * Stripe支付回調-成功鏈接
     */
    public function StripeRechargeSuccess(Request $request){
        $user_id = $request->get('user_id');//訂單ID
        $success = $request->get('success');
        $recharge_money = $request->get('recharge_money');
        try {
            DB::beginTransaction();
            // 支付完成更改用戶信息
            $effects=$this->RechargeComplete($user_id, $recharge_money ,2);// 支付完成更改用戶信息
            if(!empty($effects)){
                DB::commit();
                //支付完成
                if($this->language == "en" ){
                    return view('Payment/en_Success');
                }else{
                    return view('Payment/Success');
                }
            }else{
                DB::rollBack();
                // 支付不成功，退款
                // $returnInfo = $this->Striperefund($RefundId);
                //支付失敗
                if($this->language == "en" ){
                    return view('Payment/en_Error');
                }else{
                    return view('Payment/Error');
                }
            }
        } catch (Exception $e) {
            //支付失敗
            // return  $e->getMessage();
            if($this->language == "en" ){
                return view('Payment/en_Error');
            }else{
                return view('Payment/Error');
            }
        }
    }

    /**
     * @param Request $request
     * @return array
     * Stripe支付回調-失敗
     */
    public function StripeRechargeError(Request $request){
            //支付失敗
            // return  $e->getMessage();
            if($this->language == "en" ){
                return view('Payment/en_Error');
            }else{
                return view('Payment/Error');
            }
    }




/**************************************************支付完成訂單修改****************************************************************************/
    /**
     * @param Request $request
     * @return array
     * 支付完成訂單修改
     */
    public function RechargeComplete($user_id,$recharge_money ,$payment_mode=1){
        DB::beginTransaction();
        try {
           $UserBalance = User::where('user_id',$user_id)->increment('user_balance',$recharge_money);
            //添加钱包记录
            $WalletInfo = [
                'user_id' => $user_id,
                'wallet_type' => 2,
                'payment_mode' => $payment_mode,
                'wallet_explain'=>'賬號充值',
                'en_wallet_explain'=>'Account recharge',
                'wallet_money' => $recharge_money,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];
            $effects=UserWalletRecord::insert($WalletInfo);
            if(!empty($effects)){
                $UserInfo = User::where('user_id',$user_id)->select('user_id','user_email','client_id','token_type')->first();
                $en_Message = 'The account is successfully recharged, and the recharged amount is '.$recharge_money.' !';
                $Message = '賬號充值成功，充值金額 '.$recharge_money.' !';
                  //加入系統消息
                $SystemInfo = new SystemInfo();
                $code=$SystemInfo->addSystemInfo($user_id, 3 , $Message , $en_Message);
                if(!empty($code)){
                    $SendMessage= $this->language == "en" ? $en_Message : $Message;
                    if(!empty($UserInfo['user_email'])){
                        //邮箱推送
                        $EmailInfo['Email']=$UserInfo['user_email'];
                        $EmailInfo['Message']=$SendMessage;
                        $mail = new MailController();
                        @$mail->MessageEmails($EmailInfo);
                    }
                    //加入推送消息
                    if(!empty($UserInfo['client_id'])){
                        $GeTui = new GeTuiController();
                        @$PushInfo = $GeTui->pushToSingleByCid($UserInfo['client_id'],'Recharge',$SendMessage, 1);
                    }
                }
                DB::commit(); 
                return  true;
            }else{
                DB::rollBack();
                return  false;
                
            }
        }catch (\Exception $e) {
            DB::rollBack(); 
            return  false;
        }       
    }



    
    

/**************************************************end****************************************************************************/
}
